/*
 * Copyright (C) 2010 Graham Allan
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.strath.cis.grallan.findbugs.adaptiveranking;

import static edu.strath.cis.grallan.findbugs.adaptiveranking.UserDesignationToPositivesMap.Positive.FALSE_POSITIVE;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.cloud.Cloud.UserDesignation;

/**
 * Maps a {@link UserDesignation} to a classification of either true or false positive.
 * 
 * @author Graham Allan (grallan@cis.strath.ac.uk)
 */
public class UserDesignationToPositivesMap {

	public enum Positive {
		TRUE_POSITIVE, FALSE_POSITIVE, NEUTRAL
	}

	/**
	 * Takes a UserDesignation returns a status for whether the designation indicates a true or
	 * false positive.
	 * 
	 * Some designations do not fit into a true or false positive, i.e. Unclassified. These are
	 * designated to {@link Positive#NEUTRAL}.
	 * 
	 * Note that this mapper cannot automatically track new additions of UserDesignations in newer
	 * versions of Findbugs. If a new UserDesignation is added which this mapper does not recognise,
	 * this method will return {@link Positive#NEUTRAL}.
	 * 
	 * Currently the designations map to Positive values as follows: <br>
	 * <br>
	 * TRUE_POSITIVE: UserDesignation.{MUST_FIX,SHOULD_FIX,I_WILL_FIX} <br>
	 * FALSE_POSITIVE: UserDesignation.{BAD_ANALYSIS,MOSTLY_HARMLESS,NOT_A_BUG,OBSOLETE_CODE} <br>
	 * NEUTRAL: UserDesignation.{UNCLASSIFIED,NEEDS_STUDY} <br>
	 * 
	 * @param designation
	 * @return {@link Positive#TRUE_POSITIVE}, {@link Positive#FALSE_POSITIVE} or
	 *         {@link Positive#NEUTRAL}
	 */
	public Positive from(UserDesignation designation) {
		switch (designation) {
		case MUST_FIX:
		case SHOULD_FIX:
		case I_WILL_FIX:
			return Positive.TRUE_POSITIVE;
		case BAD_ANALYSIS:
		case MOSTLY_HARMLESS:
		case NOT_A_BUG:
		case OBSOLETE_CODE:
			return FALSE_POSITIVE;
		case UNCLASSIFIED:
		case NEEDS_STUDY:
			return Positive.NEUTRAL;
		default:
			// TODO: Find appropriate log and log the default matching.
			return Positive.NEUTRAL;
		}

	}

	public Positive getPositiveDesignationFromBug(BugInstance bug) {
		UserDesignation userDesignation = getUserDesignationFromBug(bug);
		Positive positive = from(userDesignation);
		return positive;
	}

	private UserDesignation getUserDesignationFromBug(BugInstance bug) {
		String userDesignationKey = bug.getUserDesignationKey();
		UserDesignation userDesignation = UserDesignation.valueOf(userDesignationKey);
		return userDesignation;
	}

	public boolean bugHasThisDesignation(BugInstance bug, Positive positiveDesignation) {
		return getPositiveDesignationFromBug(bug) == positiveDesignation;
	}

}
